package imaSyncPull

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"sync"
	"time"
)

var (
	baseURL      = ""
	tokenURL     = "/ims-idas/oauth/IToken"
	deptListURL  = "/ims-idms/sysorg/list"
	userListURL  = "/ims-idms/sysuser/page"
	authUser     = ""
	authPassword = ""
	authKey      = ""
)

type tokenResponse struct {
	AccessToken string `json:"access_token"`
	TokenType   string `json:"token_type"`
	Error       string `json:"error"`
	ErrorDesc   string `json:"error_description"`
}

type Department struct {
	ID       int          `json:"id"`
	ParentID string       `json:"parentId"`
	Name     string       `json:"name"`
	DelFlag  string       `json:"delFlag"`
	Sort     int          `json:"sort"`
	Children []Department `json:"children"`
}

type DeptResponse struct {
	Code    int          `json:"code"`
	Success bool         `json:"success"`
	Data    []Department `json:"data"`
	Msg     string       `json:"msg"`
}

type User struct {
	ID         string `json:"id"`
	OrgID      int    `json:"orgId"`
	LoginName  string `json:"loginName"`
	No         string `json:"no"`
	Name       string `json:"name"`
	Email      string `json:"email"`
	Phone      string `json:"phone"`
	Mobile     string `json:"mobile"`
	LoginFlag  string `json:"loginFlag"`
	DelFlag    string `json:"delFlag"`
	Sort       int    `json:"sort"`
	Gender     int    `json:"gender"`
	UserStatus string `json:"userStatus"`
}

type UserListResponse struct {
	Code    int  `json:"code"`
	Success bool `json:"success"`
	Data    struct {
		Records []User `json:"records"`
		Total   int    `json:"total"`
		Size    int    `json:"size"`
		Current int    `json:"current"`
		Pages   int    `json:"pages"`
	} `json:"data"`
	Msg string `json:"msg"`
}

var (
	tokenCache     string
	tokenExpiry    time.Time
	tokenCacheLock sync.RWMutex
)

// sendRequest 处理HTTP请求的通用方法
func sendRequest(method, url string, params url.Values, useToken bool) ([]byte, error) {
	var req *http.Request
	var err error

	var fullURL = baseURL + url

	if method == "POST" {
		req, err = http.NewRequest(method, fullURL, strings.NewReader(params.Encode()))
		if err != nil {
			return nil, fmt.Errorf("创建请求失败: %v", err)
		}
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	} else {
		req, err = http.NewRequest(method, fullURL+"?"+params.Encode(), nil)
		if err != nil {
			return nil, fmt.Errorf("创建请求失败: %v", err)
		}
	}

	if useToken {
		token, err := getToken()
		if err != nil {
			return nil, fmt.Errorf("获取token失败: %v", err)
		}
		req.Header.Set("Blade-Auth", "bearer "+token)
	}

	// 忽略证书
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{
		Transport: tr,
	}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	var buf bytes.Buffer
	_, err = buf.ReadFrom(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应失败: %v", err)
	}

	return buf.Bytes(), nil
}

// getToken 获取认证token
func getToken() (string, error) {
	tokenCacheLock.RLock()
	if tokenCache != "" && time.Now().Before(tokenExpiry) {
		defer tokenCacheLock.RUnlock()
		return tokenCache, nil
	}
	tokenCacheLock.RUnlock()

	tokenCacheLock.Lock()
	defer tokenCacheLock.Unlock()

	// Double check
	if tokenCache != "" && time.Now().Before(tokenExpiry) {
		return tokenCache, nil
	}

	params := url.Values{}
	params.Set("userInfo", authUser)
	params.Set("password", authPassword)
	params.Set("auth", authKey)

	respData, err := sendRequest("POST", tokenURL, params, false)
	if err != nil {
		return "", err
	}

	var tokenResp tokenResponse
	if err := json.Unmarshal(respData, &tokenResp); err != nil {
		return "", fmt.Errorf("解析token响应失败: %v", err)
	}

	if tokenResp.Error != "" {
		return "", fmt.Errorf("获取token失败: %s - %s", tokenResp.Error, tokenResp.ErrorDesc)
	}

	if tokenResp.AccessToken == "" {
		return "", fmt.Errorf("获取token失败: 响应中没有access_token")
	}

	tokenCache = tokenResp.AccessToken
	tokenExpiry = time.Now().Add(2 * time.Hour)

	return tokenCache, nil
}

// GetAllDepartments 获取所有部门信息
func GetAllDepartments() ([]Department, error) {
	params := url.Values{}
	// params.Set("parentId", "0")

	respData, err := sendRequest("GET", deptListURL, params, true)
	if err != nil {
		return nil, err
	}

	var deptResp DeptResponse
	if err := json.Unmarshal(respData, &deptResp); err != nil {
		return nil, fmt.Errorf("解析部门响应失败: %v", err)
	}

	if !deptResp.Success || deptResp.Code != 200 {
		return nil, fmt.Errorf("获取部门列表失败: %s", deptResp.Msg)
	}

	// 如果根部门数组少于1个，就返回错误。
	if len(deptResp.Data) < 1 {
		return nil, fmt.Errorf("部门数量不足1: %d", len(deptResp.Data))
	}
	// 如果第一个部门的子部门数量少于2个，就返回错误。
	if len(deptResp.Data[0].Children) < 2 {
		return nil, fmt.Errorf("根部门子部门数量不足2: %d", len(deptResp.Data[0].Children))
	}

	return deptResp.Data, nil
}

// GetAllUsers 获取所有用户信息
func GetAllUsers() ([]User, error) {
	var allUsers []User
	current := 1
	size := 1000

	for {
		params := url.Values{}
		params.Set("current", fmt.Sprintf("%d", current))
		params.Set("size", fmt.Sprintf("%d", size))

		respData, err := sendRequest("GET", userListURL, params, true)
		if err != nil {
			return nil, fmt.Errorf("发送用户列表请求失败: %v", err)
		}

		var userResp UserListResponse
		if err := json.Unmarshal(respData, &userResp); err != nil {
			return nil, fmt.Errorf("解析用户响应失败: %v", err)
		}

		if !userResp.Success || userResp.Code != 200 {
			return nil, fmt.Errorf("获取用户列表失败: %s", respData)
		}

		// 如果没有用户记录，直接返回错误
		if current == 1 {
			if userResp.Data.Records == nil {
				return nil, fmt.Errorf("没有找到用户记录")
			}
			if len(userResp.Data.Records) == 0 {
				return nil, fmt.Errorf("用户记录为0")
			}
		}

		if len(userResp.Data.Records) == 0 {
			break
		}

		allUsers = append(allUsers, userResp.Data.Records...)

		if current >= userResp.Data.Pages {
			break
		}
		current++
	}

	return allUsers, nil
}
